import resource
import time

from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
from starlette.requests import Request, HTTPConnection
from starlette.responses import Response
from starlette.types import ASGIApp, Receive, Send, Scope

from common.pkg.str_id import get_short_uuid, get_id_with_date_info


def _get_cpu_time() -> float:
    resources = resource.getrusage(resource.RUSAGE_SELF)
    return resources[0] + resources[1]


class TimingMiddleware(BaseHTTPMiddleware):
    def __init__(self, app: ASGIApp):
        super().__init__(app)

    async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) -> Response:
        response = await call_next(request)
        return response

    async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
        from common.g.g import G_LOGGER
        if scope["type"] not in ["http", "websocket"]:
            await self.app(scope, receive, send)
            return
        conn = HTTPConnection(scope)
        start_time = time.time() * 1000
        cpu_start_time = _get_cpu_time() * 1000
        await self.app(scope, receive, send)
        t1 = time.time() * 1000 - start_time
        t2 = _get_cpu_time() * 1000 - cpu_start_time
        G_LOGGER.info(f"{conn.client.host}:{conn.client.port} | {scope.get('method')} | {conn.url.path} | total:{t1:6.1f}ms | CPU:{t2:6.1f}ms")



